﻿using System;
using System.Data;
using System.Runtime.Versioning;
using System.Windows.Forms;

namespace zykControl
{
    /// <summary>
    /// 项选择窗体
    /// </summary>
    /// <remarks></remarks>
    [SupportedOSPlatform("windows")]
    public partial class FrmItemSel
    {
        /// <summary>
        /// 项选择窗体
        /// </summary>
        public FrmItemSel(CItemSelBase theItemSel)
        {
            InitializeComponent();
            mItemSel = theItemSel;
        }

        private readonly CItemSelBase mItemSel;
        private bool mIsOK;

        /// <summary>
        /// 弹出项选择窗体
        /// </summary>
        /// <param name="theItemSel"></param>
        /// <param name="theInputText"></param>
        /// <returns></returns>
        public static string? ShowA(CItemSelBase theItemSel, string theInputText = "")
        {
            var dI = new FrmItemSel(theItemSel) { Text = theItemSel.Title };
            dI.txtFind.Text = theInputText.Trim();
            if (theItemSel.Width > 0) dI.Width = theItemSel.Width;
            if (theItemSel.Height > 0) dI.Height = theItemSel.Height;
            dI.mIsOK = false;
            dI.RefreshMe(true);
            var dTable = (DataTable)dI.dgvList.DataSource;
            if (dTable != null && dTable.Rows.Count == 1) return dTable.Rows[0][0].ToString();

            if (theItemSel.WidthsDefault != null) dI.dgvList.LoadLayout(theItemSel.KeyMain, theItemSel.ModuleName);
            dI.ShowDialog();
            if (theItemSel.WidthsDefault != null) dI.dgvList.SaveLayout();
            if (dI.mIsOK)
                return dI.dgvList.SelectedRow?.Cells[0].Value.ToString();
            else
                return null;
        }

        /// <summary>
        /// 从DataTable当中的一个列,创建一个DataGridView的列
        /// </summary>
        /// <param name="theDataColumn"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        private static DataGridViewColumn CreateGridColumn(DataColumn theDataColumn)
        {
            DataGridViewColumn dColumn;
            switch (true)
            {
                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(string)):
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 100 };
                        break;
                    }

                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(int)):
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 50 };
                        if (theDataColumn.ColumnName.Length > 3)
                            dColumn.Width = 60;
                        if (theDataColumn.ColumnName.Length > 4)
                            dColumn.Width = 70;
                        dColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                        break;
                    }

                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(double)):
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 65 };
                        dColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                        dColumn.DefaultCellStyle.Format = "0.##";
                        break;
                    }

                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(decimal)):
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 65 };
                        dColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                        dColumn.DefaultCellStyle.Format = "0.00";
                        break;
                    }

                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(DateTime)):
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 105 };
                        if (theDataColumn.ExtendedProperties.ContainsKey("Format"))
                        {
                            dColumn.DefaultCellStyle.Format = theDataColumn.ExtendedProperties["Format"]?.ToString();
                        }
                        else
                        {
                            dColumn.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm";
                        }

                        break;
                    }

                case object _ when ReferenceEquals(theDataColumn.DataType, typeof(bool)):
                    {
                        dColumn = new DataGridViewCheckBoxColumn() { Width = 35 };
                        if (theDataColumn.ColumnName.Length > 1)
                            dColumn.Width = 40;
                        dColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
                        break;
                    }

                default:
                    {
                        dColumn = new DataGridViewTextBoxColumn() { Width = 100 };
                        break;
                    }
            }

            dColumn.DataPropertyName = theDataColumn.ColumnName;
            dColumn.HeaderText = theDataColumn.ColumnName;
            return dColumn;
        }

        /// <summary>
        /// 加载各列的宽度设置,仅应由RefreshMe使用
        /// </summary>
        /// <remarks></remarks>
        private void SetWidthsDefault()
        {
            if (mItemSel.WidthsDefault is null) { dgvList.AutoResizeColumns(); return; }

            for (int xx = 0, loopTo = mItemSel.WidthsDefault.Length - 1; xx <= loopTo; xx++)
            {
                if (xx >= dgvList.Columns.Count) return;
                if (mItemSel.WidthsDefault[xx] > 0) dgvList.Columns[xx].Width = mItemSel.WidthsDefault[xx];
            }
        }

        private void BtnClose_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void RefreshMe(bool theFirstLoad = false)
        {
            var dTable = mItemSel.RefreshItems(txtFind.Text.Trim());
            if (dTable is null)
            {
                dgvList.DataSource = null;
                return;
            }

            if (theFirstLoad)
            {
                dgvList.Columns.Clear();
                for (int xx = 0, loopTo = dTable.Columns.Count - 1; xx <= loopTo; xx++)
                {
                    var dColumn = CreateGridColumn(dTable.Columns[xx]);
                    dgvList.Columns.Add(dColumn);
                }

                dgvList.LoadLayout(mItemSel.KeyMain, mItemSel.ModuleName);
            }

            dgvList.DataSource = dTable;
            dgvList.Refresh();
            SetWidthsDefault();
        }

        private void TxtFind_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    {
                        e.Handled = true;
                        dgvList.MoveUpSelect();
                        break;
                    }

                case Keys.Down:
                    {
                        e.Handled = true;
                        dgvList.MoveDownSelect();
                        break;
                    }

                case Keys.Enter:
                    {
                        DgvList_DoubleClick(sender, e);
                        break;
                    }
            }
        }

        private void DgvList_DoubleClick(object sender, EventArgs e)
        {
            if (dgvList.Selected)
            {
                mIsOK = true;
                Close();
            }
        }

        private void TxtFind_TextChanged(object sender, EventArgs e)
        {
            if (Created == false)
                return;
            if (mItemSel is null)
                return;
            RefreshMe();
        }

        private void TxtFind_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == '\r') e.Handled = true;
        }

        private void TxtFind_Enter(object sender, EventArgs e)
        {
            txtFind.SelectAll();
        }
    }

    /// <summary>
    /// 项选择窗体的适配类,必须继承使用
    /// </summary>
    /// <remarks></remarks>
    /// <remarks>
    /// 项选择窗体的适配类,必须继承使用
    /// </remarks>
    /// <param name="theKeyMain"></param>
    /// <param name="theModuleName"></param>
    /// <param name="theWidth"></param>
    /// <param name="theHeight"></param>
    /// <param name="theTitle"></param>
    public abstract class CItemSelBase(string theKeyMain, string theModuleName, int theWidth = 0, int theHeight = 0, string theTitle = "请选择一项")
    {
        /// <summary>
        /// 刷新明细时执行的函数,如果时间的格式与默认格式不同,请为DataColumn.ExtendedProperties添加一个以Format为键的格式化文本
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public abstract DataTable RefreshItems(string theSelText);

        /// <summary>
        /// 列表的默认宽度,只应在New中设置
        /// </summary>
        /// <value></value>
        /// <returns></returns>
        /// <remarks></remarks>
        public int[]? WidthsDefault { get; set; } = null;
        internal int Width { get; private set; } = theWidth;
        internal int Height { get; private set; } = theHeight;
        internal string KeyMain { get; private set; } = theKeyMain;
        internal string ModuleName { get; private set; } = theModuleName;
        internal string Title { get; private set; } = theTitle;
    }
}